#include <iostream>
#include <vector>
#include <queue>

using namespace std;

typedef vector<char> vchar;
typedef vector< vector<char> > vvchar;
typedef vector<bool> v1dim; 
typedef vector< vector<bool> > v2dim; 
typedef vector< vector< vector<bool> > > v3dim; 
typedef vector< vector< vector< vector<bool> > > > v4dim; 
typedef vector< vector< vector< vector< vector<bool> > > > > v5dim; 
typedef vector< vector< vector< vector< vector< vector<bool> > > > > > v6dim;
typedef pair<int,int> par;
typedef vector< pair<int,int> > vpar;

// Defino la estructura que serán los nodos del bfs
struct estado{ 
    par p1; 	
    par p2; // Formado por 3 posiciones y una cantidad de pasos desde el estado inicial
    par p3; 
    int paso; 
};
typedef struct estado est; // Facilito la lectura

// Igualdad de pares
bool igualPar(par &p1, par &p2){
    return p1.first == p2.first && p1.second == p2.second;
}
    
// Captura la matriz de entrada
void capturarEntrada(vvchar &game, vector<par> &final, est &inicial, int n){
    
    char temp;
    int pos = 0;
    for (int i = 0; i < n; i ++){
		for(int j = 0; j < n; j++){
			cin >> temp;
			game[i][j] = temp;
			if (temp == 'X'){
				final[pos].first = i;
				final[pos].second = j;
				pos++;
			}
			if (temp == 'A'){
				inicial.p1.first = i;
				inicial.p1.second = j;
			}
			if (temp == 'B'){
				inicial.p2.first = i;
				inicial.p2.second = j;
			}
			if (temp == 'C'){
				inicial.p3.first = i;
				inicial.p3.second = j;
			}
		}
    }
}

// Llena con los estados visitados
void llenarVisitados(est &estado, v6dim &vis){

    int posP1X = estado.p1.first; // Primer elemento de la posicion de una de las personas
    int posP1Y = estado.p1.second; // Segundo elemento de la posicion de una de las personas
    int posP2X = estado.p2.first;
    int posP2Y = estado.p2.second;
    int posP3X = estado.p3.first;
    int posP3Y = estado.p3.second;
    
    vis[posP1X][posP1Y][posP2X][posP2Y][posP3X][posP3Y] = true;
    vis[posP1X][posP1Y][posP3X][posP3Y][posP2X][posP2Y] = true; // LLeno todas las posibles combinaciones ya que el orden luego no me va a importar
    vis[posP2X][posP2Y][posP1X][posP1Y][posP3X][posP3Y] = true;
    vis[posP2X][posP2Y][posP3X][posP3Y][posP1X][posP1Y] = true;
    vis[posP3X][posP3Y][posP1X][posP1Y][posP2X][posP2Y] = true;
    vis[posP3X][posP3Y][posP2X][posP2Y][posP1X][posP1Y] = true;

}


// Analiza si un estado es el estado final
bool esEstadoFinal(est &estado, vector<par> &final){

    int posP1X = estado.p1.first; // Primer elemento de la posicion de una de las personas
    int posP1Y = estado.p1.second; // Segundo elemento de la posicion de una de las personas
    int posP2X = estado.p2.first;
    int posP2Y = estado.p2.second;
    int posP3X = estado.p3.first;
    int posP3Y = estado.p3.second;
    int fin1X = final[0].first; // Primer elemento de la posicion de una salida
    int fin1Y = final[0].second; // Segundo elemento de la posicion de una salida
    int fin2X = final[1].first;
    int fin2Y = final[1].second;
    int fin3X = final[2].first;
    int fin3Y = final[2].second;
    
    bool p1Final = ((posP1X == fin1X && posP1Y == fin1Y) || (posP1X == fin2X && posP1Y == fin2Y) || (posP1X == fin3X && posP1Y == fin3Y));    
    bool p2Final =((posP2X == fin1X && posP2Y == fin1Y) || (posP2X == fin2X && posP2Y == fin2Y) || (posP2X == fin3X && posP2Y == fin3Y));    
    bool p3Final = ((posP3X == fin1X && posP3Y == fin1Y) || (posP3X == fin2X && posP3Y == fin2Y) || (posP3X == fin3X && posP3Y == fin3Y));    
    
    return (p1Final && p2Final && p3Final);
}

// Se fija si un nodo ya fue visitado
bool estaVisitado(est &estado, v6dim &vis){

    int posP1X = estado.p1.first;  // Primer elemento de la posicion de una de las personas
    int posP1Y = estado.p1.second; // Segundo elemento de la posicion de una de las personas
    int posP2X = estado.p2.first;
    int posP2Y = estado.p2.second;
    int posP3X = estado.p3.first;
    int posP3Y = estado.p3.second;
    
    return vis[posP1X][posP1Y][posP2X][posP2Y][posP3X][posP3Y];
}

// Los siguientes ordenar ordenan posiciones de acuerdo a cual deberia mover primero
void ordenarAbajo(vector<par> &ord, est &estado){

    int posP1X = estado.p1.first; 
    int posP2X = estado.p2.first;
    int posP3X = estado.p3.first;
    
    if(posP1X >= posP2X){
		if(posP1X >= posP3X){
			if(posP2X >= posP3X){
				ord[0] = estado.p1;
				ord[1] = estado.p2;
				ord[2] = estado.p3;
			} else {
				ord[0] = estado.p1;
				ord[1] = estado.p3;
				ord[2] = estado.p2;
			}
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p1;
			ord[2] = estado.p2;
		}
    } else{
		if(posP2X >= posP3X){
			if(posP1X >= posP3X){
				ord[0] = estado.p2;
				ord[1] = estado.p1;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p2;
				ord[1] = estado.p3;
				ord[2] = estado.p1;
			}    
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p2;
			ord[2] = estado.p1;
		}
	}
}

void ordenarArriba(vector<par> &ord, est &estado){

    int posP1X = estado.p1.first; 
    int posP2X = estado.p2.first;
    int posP3X = estado.p3.first;
    
    if(posP1X <= posP2X){
		if(posP1X <= posP3X){
			if(posP2X <= posP3X){
				ord[0] = estado.p1;
				ord[1] = estado.p2;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p1;
				ord[1] = estado.p3;
				ord[2] = estado.p2;
			}
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p1;
			ord[2] = estado.p2;
		}
    } else{
		if(posP2X <= posP3X){
			if(posP1X <= posP3X){
				ord[0] = estado.p2;
				ord[1] = estado.p1;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p2;
				ord[1] = estado.p3;
				ord[2] = estado.p1;
			}    
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p2;
			ord[2] = estado.p1;
		}
	}
}

void ordenarIzquierda(vector<par> &ord, est &estado){
 
    int posP1Y = estado.p1.second;
    int posP2Y = estado.p2.second;
    int posP3Y = estado.p3.second;
    
    if(posP1Y <= posP2Y){
		if(posP1Y <= posP3Y){
			if(posP2Y <= posP3Y){
				ord[0] = estado.p1;
				ord[1] = estado.p2;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p1;
				ord[1] = estado.p3;
				ord[2] = estado.p2;
			}
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p1;
			ord[2] = estado.p2;
		}
    } else{
		if(posP2Y <= posP3Y){
			if(posP1Y <= posP3Y){
				ord[0] = estado.p2;
				ord[1] = estado.p1;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p2;
				ord[1] = estado.p3;
				ord[2] = estado.p1;
			}    
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p2;
			ord[2] = estado.p1;
		}
	}
}


void ordenarDerecha(vector<par> &ord, est &estado){

    int posP1Y = estado.p1.second;
    int posP2Y = estado.p2.second;
    int posP3Y = estado.p3.second;
    
    if(posP1Y >= posP2Y){
		if(posP1Y >= posP3Y){
			if(posP2Y >= posP3Y){
				ord[0] = estado.p1;
				ord[1] = estado.p2;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p1;
				ord[1] = estado.p3;
				ord[2] = estado.p2;
			}
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p1;
			ord[2] = estado.p2;
		}
    } else{
		if(posP2Y >= posP3Y){
			if(posP1Y >= posP3Y){
				ord[0] = estado.p2;
				ord[1] = estado.p1;
				ord[2] = estado.p3;
			} else{
				ord[0] = estado.p2;
				ord[1] = estado.p3;
				ord[2] = estado.p1;
			}    
		} else{
			ord[0] = estado.p3;
			ord[1] = estado.p2;
			ord[2] = estado.p1;
		}
	}
}

// Dada una posicion devuelve la ubicacion de tal en el arreglo ordenado
int damePos(vector<par> &ord, par &pi){    
    for(int k = 0; k < 3; k++){
		if (igualPar(ord[k], pi)){
			return k;	        
		}
    }
    return 0;
}

// Asigna el movimiento a la persona correspondiente
void asignarAdecuado(vector<par> &ord, vector<par> &sig, est &actual, est &siguiente){
    siguiente.p1 = sig[damePos(ord, actual.p1)];	
    siguiente.p2 = sig[damePos(ord, actual.p2)],
    siguiente.p3 = sig[damePos(ord, actual.p3)];
}

// Las siguientes funciones mueven en una determinada posicion a los jugadores
void moverAbajo(vector<par> &ord, est &siguiente, est &actual, vvchar &data, int n){
    
    int posP1Y = ord[0].second;
    int posP2Y = ord[1].second;
    int posP3Y = ord[2].second;
    int posP1X = ord[0].first;
    int posP2X = ord[1].first;
    int posP3X = ord[2].first;
    par pos_sig(0,0);
    vector<par> sig(3, pos_sig);
    sig[0].second = posP1Y;
    sig[1].second = posP2Y;
    sig[2].second = posP3Y;
    sig[0].first = posP1X + 1;
    sig[1].first = posP2X + 1;
    sig[2].first = posP3X + 1;
    
    if((posP1X == n - 1) || data[posP1X + 1][posP1Y] == '#'){
		sig[0].first--;
    }		
    if((posP2X == n - 1) || (data[posP2X + 1][posP2Y] == '#') || (posP2Y == posP1Y && posP2X + 1 == sig[0].first)){
		sig[1].first--;
    }
    
    if((posP3X == n - 1) || (data[posP3X + 1][posP3Y] == '#') || (posP3Y == posP2Y && posP3X + 1 == sig[1].first) || (posP3Y == posP1Y && posP3X + 1 == sig[0].first)){
		sig[2].first--;
    }
    asignarAdecuado(ord, sig, actual, siguiente);
}

void moverArriba(vector<par> &ord, est &siguiente, est &actual, vvchar &data){
    
    int posP1Y = ord[0].second;
    int posP2Y = ord[1].second;
    int posP3Y = ord[2].second;
    int posP1X = ord[0].first;
    int posP2X = ord[1].first;
    int posP3X = ord[2].first;
    par pos_sig(0,0);
    vector<par> sig(3, pos_sig);
    sig[0].second = posP1Y;
    sig[1].second = posP2Y;
    sig[2].second = posP3Y;
    sig[0].first = posP1X - 1;
    sig[1].first = posP2X - 1;
    sig[2].first = posP3X - 1;
    
    if((posP1X == 0) || data[posP1X - 1][posP1Y] == '#'){
		sig[0].first++;
    }		
    if((posP2X == 0) || (data[posP2X - 1][posP2Y] == '#') || (posP2Y == posP1Y && posP2X - 1 == sig[0].first)){
		sig[1].first++;
    }
    if((posP3X == 0) || (data[posP3X - 1][posP3Y] == '#') || (posP3Y == posP2Y && posP3X - 1 == sig[1].first) || (posP3Y == posP1Y && posP3X - 1 == sig[0].first)){
		sig[2].first++;
    }
    asignarAdecuado(ord, sig, actual, siguiente);
}


void moverDerecha(vector<par> &ord, est &siguiente, est &actual, vvchar &data, int n){
    
    int posP1Y = ord[0].second;
    int posP2Y = ord[1].second;
    int posP3Y = ord[2].second;
    int posP1X = ord[0].first;
    int posP2X = ord[1].first;
    int posP3X = ord[2].first;
    par pos_sig(0,0);
    vector<par> sig(3, pos_sig);
    sig[0].second = posP1Y + 1;
    sig[1].second = posP2Y + 1;
    sig[2].second = posP3Y + 1;
    sig[0].first = posP1X;
    sig[1].first = posP2X;
    sig[2].first = posP3X;
    
    if((posP1Y == n - 1) || data[posP1X][posP1Y + 1] == '#'){
		sig[0].second--;
    }		
    if((posP2Y == n - 1) || (data[posP2X][posP2Y + 1] == '#') || (posP2X == posP1X && posP2Y + 1 == sig[0].second)){
		sig[1].second--;
    }
    if((posP3Y == n - 1) || (data[posP3X][posP3Y + 1] == '#') || (posP3X == posP2X && posP3Y + 1 == sig[1].second) || (posP3X == posP1X && posP3Y + 1 == sig[0].second)){
		sig[2].second--;
    }
    asignarAdecuado(ord, sig, actual, siguiente);
}

void moverIzquierda(vector<par> &ord, est &siguiente, est &actual, vvchar &data){
    
    int posP1Y = ord[0].second;
    int posP2Y = ord[1].second;
    int posP3Y = ord[2].second;
    int posP1X = ord[0].first;
    int posP2X = ord[1].first;
    int posP3X = ord[2].first;
    par pos_sig(0,0);
    vector<par> sig(3, pos_sig);
    sig[0].second = posP1Y - 1;
    sig[1].second = posP2Y - 1;
    sig[2].second = posP3Y - 1;
    sig[0].first = posP1X;
    sig[1].first = posP2X;
    sig[2].first = posP3X;
    
    if((posP1Y == 0) || data[posP1X][posP1Y - 1] == '#'){
		sig[0].second++;
    }		
    if((posP2Y == 0) || (data[posP2X][posP2Y - 1] == '#') || (posP2X == posP1X && posP2Y - 1 == sig[0].second)){
		sig[1].second++;
    }
    if((posP3Y == 0) || (data[posP3X][posP3Y - 1] == '#') || (posP3X == posP2X && posP3Y - 1 == sig[1].second) || (posP3X == posP1X && posP3Y - 1 == sig[0].second)){
		sig[2].second++;
    }
    asignarAdecuado(ord, sig, actual, siguiente);    
}


// Agrega los posibles vecinos a la cola
void agregarVecinos(est &estado, queue<est> &cola, v6dim &vis, vvchar &data, int n){

    par ini(0,0);
    vector<par> izq(3, ini);
    vector<par> der(3, ini);
    vector<par> arr(3, ini);
    vector<par> abj(3, ini);
    est vec1;
    est vec2;
    est vec3;
    est vec4;
    vec1.paso = estado.paso + 1;
    vec2.paso = estado.paso + 1;
    vec3.paso = estado.paso + 1;
    vec4.paso = estado.paso + 1;   
    
    ordenarArriba(arr, estado);
    ordenarAbajo(abj, estado);
    ordenarDerecha(der, estado);
    ordenarIzquierda(izq, estado);
    
    moverArriba(arr, vec1, estado, data);
    moverAbajo(abj, vec2, estado, data, n);
    moverIzquierda(izq, vec3, estado, data);
    moverDerecha(der, vec4, estado, data, n);
    
    if (!estaVisitado(vec1, vis)){
		cola.push(vec1);
		llenarVisitados(vec1, vis);
    }
    if (!estaVisitado(vec2, vis)){
		cola.push(vec2);
		llenarVisitados(vec2, vis);
    }
    if (!estaVisitado(vec3, vis)){
		cola.push(vec3);
		llenarVisitados(vec3, vis);
    }
    if (!estaVisitado(vec4, vis)){
		cola.push(vec4);
		llenarVisitados(vec4, vis);
    }
}

// Realiza el BFS deseado
int BFS(est &inicial, vector<par> &final, v6dim &vis, vvchar &data, int n){

    queue<est> cola;
    cola.push(inicial);
    int res = -1;
    while((!(cola.empty()) && (res < 0))){
		if (esEstadoFinal(cola.front(), final)){
			res = cola.front().paso;
		} else{
			agregarVecinos(cola.front(), cola, vis, data, n);
		}    
		cola.pop();
    }
    return res;
}

int main() {
    int n;
    int casos;
    int casoi;
    int res;
    res = 0;
    cin >> casos;
    casoi = 1;
    while(casos > 0) {
		cin >> n;
		vvchar data(n, vchar(n, '-')); 
		v6dim visitados(n, v5dim(n, v4dim(n, v3dim(n, v2dim(n, v1dim(n, false))))));	
		par inicial(0,0);
		vpar estadoFinal(3, inicial);
		est estadoInicial;
		estadoInicial.paso = 0;
		capturarEntrada(data, estadoFinal, estadoInicial, n);
		llenarVisitados(estadoInicial, visitados);
		res = BFS(estadoInicial, estadoFinal, visitados, data, n);	
	
		if (res == -1){      
			cout << "Case " << casoi << ": trapped" << endl;
		} else {
			cout << "Case " << casoi << ": " << res << endl;
		} 
		casoi++;     
        casos--;       
    }
        
    return 0;
}
